﻿using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace RTW.OA.SignalR
{
    public class MessageHub : Hub<IClientMessageHub>
    {
        private static ConcurrentDictionary<string, UserModel> OnLineUsers = new ConcurrentDictionary<string, UserModel>();

        public void SendData(dynamic data)
        {
            data.time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            Clients.All.ReceiveData(data);
        }

        public void SendMessage(MessageModel message)
        {
            Clients.All.ReceiveMessage(message);
        }

        public void SendDataToUser(string userId, dynamic data)
        {
            data.userId = userId;
            data.time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            var users = OnLineUsers.Where(a => a.Value.UserId == userId);
            if (users != null && users.Count() > 0)
            {
                var connectionIds = users.Select(a => a.Value.ConnectionId).ToList();
                Clients.Clients(connectionIds).ReceiveData(data);
            }
        }

        public void SendMessageToUser(string userId, MessageModel message)
        {
            var users = OnLineUsers.Where(a => a.Value.UserId == userId);
            if (users != null && users.Count() > 0)
            {
                var connectionIds = users.Select(a => a.Value.ConnectionId).ToList();
                Clients.Clients(connectionIds).ReceiveMessage(message);
            }
        }

        public void Connection(string userId)
        {
            if (!OnLineUsers.Keys.Contains(Context.ConnectionId))
            {
                var user = new UserModel
                {
                    UserId = userId,
                    ConnectionId = Context.ConnectionId
                };
                OnLineUsers.AddOrUpdate(Context.ConnectionId, user, (key, value) => user);
            }
        }

        public void DisConnection()
        {
            if (OnLineUsers.Keys.Contains(Context.ConnectionId))
            {
                var user = OnLineUsers.SingleOrDefault(a => a.Key == Context.ConnectionId).Value;
                OnLineUsers.TryRemove(Context.ConnectionId, out user);
            }
        }

        private IEnumerable<string> GetUserConnectionIds(string userId)
        {
            this.Connection(userId);
            return OnLineUsers.Where(a => a.Value.UserId == userId).Select(a => a.Value.ConnectionId);
        }

        public void SendMessageToGroup(string groupName, MessageModel message)
        {
            Groups.Add(Context.ConnectionId, groupName);
            Clients.Group(groupName).ReceiveMessage(message);
        }

        public void JoinGroup(string groupName)
        {
            Groups.Add(Context.ConnectionId, groupName);
        }

        public void RemoveGroup(string groupName)
        {
            Groups.Remove(Context.ConnectionId, groupName);
        }
    }
}